home *** CD-ROM | disk | FTP | other *** search
- /*
- C* -- symbol table routines.
-
- source: st.c
- started: November 4, 1985
- version:
- December 24, 1986
- March 7, 1989
-
- PUBLIC DOMAIN SOFTWARE
-
- The CSTAR program was placed in the public domain on June 15, 1991,
- by its author and sole owner,
-
- Edward K. Ream
- 1617 Monroe Street
- Madison, WI 53711
- (608) 257-0802
-
- CSTAR may be used for any commercial or non-commercial purpose.
-
- See cstar.h or cstar.c for a DISCLAIMER OF WARRANTIES.
- */
-
- #include "cstar.h"
-
- /*
- Externally visible routines:
- */
- struct st_node * ast_lookup (char * symbol);
-
- struct st_node * gst_enter (char * symbol,
- struct type_node * type, int class);
- static int gst_hash (char * symbol);
- struct st_node * gst_lookup (char * symbol);
- struct st_node * lst_enter (char * symbol,
- struct type_node * type, int class);
- static int lst_hash (char * symbol);
- void lst_init (void);
- struct st_node * lst_lookup (char * symbol);
- struct st_node * rst_lookup (char * symbol);
- struct st_node * rst_enter (char * symbol,
- struct type_node * type, int class);
- void st_init (void);
- struct st_node * st_lookup (char * symbol);
-
- /*
- Internal routines:
- */
- static void st_show (struct st_node * st_ht[], int size);
- static void st_dump (void);
-
- /*
- Define the hash tables.
- */
- #define G_PRIME 101
- #define L_PRIME 101
- static struct st_node * gst_ht [G_PRIME];
- static struct st_node * lst_ht [L_PRIME];
-
- /*
- Dump all symbols of both symbol tables.
- This function is used for debugging only.
- */
-
- #ifdef SHERLOCK
- static void
- st_dump(void)
- {
- TRACEP("st_dump",
- printf("&gst_ht=%p, &lst_ht=%p, ", gst_ht,lst_ht);
- printf("*gst_ht=%p, *lst_ht=%p\n", *gst_ht, *lst_ht));
-
- printf(">> Global symbols:\n");
- st_show(gst_ht, G_PRIME);
- printf("\n>> Local symbols:\n");
- st_show(lst_ht, L_PRIME);
- printf("\n");
- }
-
- static void
- st_show(struct st_node * st_ht[], int size)
- {
- register int i;
- register struct st_node *bp;
-
- for (i = 0; i < size; i++) {
- bp = st_ht[i];
- if (bp != NULL) {
- TRACEP("st_dump",
- printf("st_show: st_ht [%d] = %p\n", i, bp));
-
- do {
- TRACEP("st_dump",
- printf("st_show: typenode %p, next %p\n",
- bp -> st_type, bp -> st_next));
-
- printf("%s/%s: ",bp -> st_name,bp -> st_alias);
- pr_sclass(bp -> st_sclass);
- printf(" ");
- if (bp -> st_type != NULL) {
- pr_type(bp -> st_type);
- printf("\n");
- }
- else {
- printf("type <NULL>\n");
- }
-
- } while (bp = bp -> st_next);
- }
- }
- }
- #endif /* SHERLOCK */
-
- /*
- Look up a symbol in the local symbol table.
- If not found, try the global symbol table.
- */
- struct st_node *
- st_lookup(register char * symbol)
- {
- register struct st_node * p;
- struct st_node * gst_lookup();
- struct st_node * lst_lookup();
-
- TRACEPB("st_lookup", printf("(%s)\n", symbol));
-
- p = lst_lookup(symbol);
- if (p != NULL) {
- RETURN_PTR("st_lookup", p);
- }
- else {
- RETURN_PTR("st_lookup", gst_lookup(symbol));
- }
- }
-
- /*
- Look up a symbol in any symbol tables are appropriate to
- scope.s_scope.
- */
- struct st_node *
- ast_lookup(symbol)
- register char * symbol;
- {
- register struct st_node * p;
- struct st_node * gst_lookup();
- struct st_node * lst_lookup();
-
- TRACEPB("ast_lookup", printf("(%s)\n", symbol));
-
- switch(scope.s_scope) {
- case PROTO_SCOPE:
- case BLOCK_SCOPE:
- /* try the block symbol table ... */
- /*
- if (p != NULL) {
- break;
- }
- */
- /* FALL_THROUGH */
-
- case FNDEF_SCOPE:
- p = lst_lookup(symbol);
- if (p != NULL) {
- break;
- }
- /* FALL_THROUGH */
-
- case FILE_SCOPE:
- p = gst_lookup(symbol);
- break;
- default:
- p = NULL;
- t_error("ast_lookup: unknown scope");
- }
- RETURN_PTR("ast_lookup", p);
- }
-
- /*
- Restricted lookup:
- Look up a symbol in the symbol table local to scope.s_scope
- It happens that this process will find the formals from the block
- scope, although this may not be correct.
- */
- struct st_node *
- rst_lookup(symbol)
- register char * symbol;
- {
- register struct st_node * p;
-
- TRACEPB("rst_lookup", printf("(%s)\n", symbol));
-
- switch(scope.s_scope) {
- case PROTO_SCOPE:
- case BLOCK_SCOPE:
- case FNDEF_SCOPE:
- RETURN_PTR("rst_lookup", lst_lookup(symbol));
-
- case FILE_SCOPE:
- RETURN_PTR("rst_lookup", gst_lookup(symbol));
- default:
- t_error("rst_lookup: unknown scope");
- }
- RETURN_PTR("rst_lookup", NULL);
- }
-
- /*
- Place a symbol in whatever table is appropriate for
- scope.s_scope.
- */
- struct st_node *
- rst_enter (symbol, type, class)
- register char * symbol;
- struct type_node * type;
- int class;
- {
- TRACEPB("rst_enter", printf("(%s, %p, %d)\n",
- symbol, type, class));
-
- switch(scope.s_scope) {
- case PROTO_SCOPE:
- case BLOCK_SCOPE:
- case FNDEF_SCOPE:
- RETURN_PTR("rst_enter", lst_enter(symbol, type, class));
-
- case FILE_SCOPE:
- RETURN_PTR("rst_enter", gst_enter(symbol, type, class));
-
- default:
- t_error("rst_enter: unknown scope");
- }
- RETURN_PTR("rst_enter", NULL);
- }
-
- /*
- Place a symbol in the global symbol table.
- Return a pointer to the created node.
- NOTE: gst_enter ought to be combined with lst_enter,
- which would make things more orderly and make it easier to
- adopt ANSI symbol tables.
-
- */
- struct st_node *
- gst_enter (register char * symbol, struct type_node * type, int class)
- {
- register struct st_node **bp0, *bp1;
-
- TRACEPB("gst_enter", printf("(%s, %p, %d)\n",
- symbol, type, class));
-
- if (symbol == NULL) {
- t_error("gst_enter: internal: NULL symbol");
- symbol = "";
- }
-
- /* Dynamically allocate space for node. */
- bp1 = CAST(struct st_node *) mg_alloc(sizeof(struct st_node));
-
- /* Hang node from hash table. */
- bp0 = &gst_ht[0];
- bp0 += gst_hash(symbol);
-
- bp1 -> st_next = *bp0;
- *bp0 = bp1;
-
- /* Fill in the name, type, and class fields. */
- bp1 -> st_alias = str_gcat("_", symbol);
- bp1 -> st_name = bp1 -> st_alias + 1;
- bp1 -> st_type = type;
- bp1 -> st_sclass = class;
-
- RETURN_PTR("gst_enter", bp1);
- }
-
- /*
- Place a symbol in the local symbol table.
- Return a pointer to the created node.
- */
- struct st_node *
- lst_enter (register char * symbol, struct type_node * type, int class)
- {
- register struct st_node **bp0, *bp1;
-
- TRACEPB("lst_enter", printf("(%s, %p, %d)\n",
- symbol, type, class));
-
- if (symbol == NULL) {
- t_error("lst_enter: internal: NULL symbol");
- symbol = "";
- }
-
- /* Dynamically allocate space for node. */
- bp1 = CAST(struct st_node *) ml_alloc(sizeof(struct st_node));
-
- /* Hang node from hash table. */
- bp0 = &lst_ht[0];
- bp0 += lst_hash(symbol);
-
- bp1 -> st_next = *bp0;
- *bp0 = bp1;
-
- /* Fill in the name and text fields. */
- bp1 -> st_alias = str_lcat("_", symbol);
- bp1 -> st_name = bp1 -> st_alias + 1;
- bp1 -> st_type = type;
- bp1 -> st_sclass = class;
-
- RETURN_PTR("lst_enter", bp1);
- }
-
- /*
- Compute the hash function for a global symbol.
- */
- static int
- gst_hash (register char * symbol)
- {
- register int hash;
-
- SL_DISABLE();
-
- for (hash = 0; *symbol; ) {
- hash *= 3;
- hash += (int) *symbol++;
- hash %= G_PRIME;
- }
- return hash;
- }
-
- /*
- Compute the hash function for a local symbol.
- */
- static int
- lst_hash (register char * symbol)
- {
- register int hash;
-
- SL_DISABLE();
-
- for (hash = 0; *symbol; ) {
- hash *= 3;
- hash += (int) *symbol++;
- hash %= L_PRIME;
- }
- return hash;
- }
-
- /*
- Initialize both symbol tables.
- */
- void
- st_init(void)
- {
- register int i;
- register struct st_node ** bp0;
-
- TICKB("st_init");
-
- /* Clear the global hash table. */
- for (i = 0, bp0 = &gst_ht[0]; i < G_PRIME; i++) {
- *bp0++ = NULL;
- }
-
- /* Clear the local hash table. */
- lst_init();
-
- TICKX("st_init");
- }
-
- /*
- Re-initialize the local symbol table.
- */
- void
- lst_init(void)
- {
- register int i;
- register struct st_node ** bp0;
-
- /* Clear the local hash table. */
-
- TICKB("lst_init");
-
- for (i = 0, bp0 = &lst_ht[0]; i < L_PRIME; i++) {
- *bp0++ = NULL;
- }
-
- TICKX("lst_init");
- }
-
- /*
- Look up a symbol in the global symbol table.
- Return a pointer to the node or NULL.
- */
- struct st_node *
- gst_lookup (register char * symbol)
- {
- register struct st_node ** bp0, *bp1;
-
- /* Calculate the hash value of the symbol. */
-
- TRACEPB("gst_lookup", printf("(%s)\n", symbol));
-
- bp0 = &gst_ht[0];
- bp0 += gst_hash(symbol);
-
- /* Search down the list of gst_nodes. */
- for (bp1 = *bp0; bp1; bp1 = bp1 -> st_next) {
-
- if(str_eq(symbol, bp1 -> st_name)) {
- /* Found. */
- RETURN_PTR("gst_lookup", bp1);
- }
- }
-
- /* Return failure. */
-
- RETURN_PTR("gst_lookup", NULL);
- }
-
- /*
- Look up a symbol in the local symbol table.
- Return a pointer to the node or NULL.
- */
- struct st_node *
- lst_lookup (register char * symbol)
- {
- register struct st_node ** bp0, *bp1;
-
- /* Calculate the hash value of the symbol. */
-
- TRACEPB("lst_lookup", printf("(%s)\n", symbol));
-
- bp0 = &lst_ht[0];
- bp0 += lst_hash(symbol);
-
- /* Search down the list of lst_nodes. */
- for (bp1 = *bp0; bp1; bp1 = bp1 -> st_next) {
-
- if(str_eq(symbol, bp1 -> st_name)) {
- /* Found. */
- RETURN_PTR("lst_lookup", bp1);
- }
- }
-
- /* Return failure. */
-
- RETURN_PTR("lst_lookup", NULL);
- }
-